#region Copyright (c) 2006-2009 Widgetsphere LLC, All Rights Reserved
//--------------------------------------------------------------------- *
//                          Widgetsphere  LLC                           *
//             Copyright (c) 2006-2009 All Rights reserved              *
//                                                                      *
//                                                                      *
//This file and its contents are protected by United States and         *
//International copyright laws.  Unauthorized reproduction and/or       *
//distribution of all or any portion of the code contained herein       *
//is strictly prohibited and will result in severe civil and criminal   *
//penalties.  Any violations of this copyright will be prosecuted       *
//to the fullest extent possible under law.                             *
//                                                                      *
//THE SOURCE CODE CONTAINED HEREIN AND IN RELATED FILES IS PROVIDED     *
//TO THE REGISTERED DEVELOPER FOR THE PURPOSES OF EDUCATION AND         *
//TROUBLESHOOTING. UNDER NO CIRCUMSTANCES MAY ANY PORTION OF THE SOURCE *
//CODE BE DISTRIBUTED, DISCLOSED OR OTHERWISE MADE AVAILABLE TO ANY     *
//THIRD PARTY WITHOUT THE EXPRESS WRITTEN CONSENT OF WIDGETSPHERE LLC   *
//                                                                      *
//UNDER NO CIRCUMSTANCES MAY THE SOURCE CODE BE USED IN WHOLE OR IN     *
//PART, AS THE BASIS FOR CREATING A PRODUCT THAT PROVIDES THE SAME, OR  *
//SUBSTANTIALLY THE SAME, FUNCTIONALITY AS ANY WIDGETSPHERE PRODUCT.    *
//                                                                      *
//THE REGISTERED DEVELOPER ACKNOWLEDGES THAT THIS SOURCE CODE           *
//CONTAINS VALUABLE AND PROPRIETARY TRADE SECRETS OF WIDGETSPHERE,      *
//INC.  THE REGISTERED DEVELOPER AGREES TO EXPEND EVERY EFFORT TO       *
//INSURE ITS CONFIDENTIALITY.                                           *
//                                                                      *
//THE END USER LICENSE AGREEMENT (EULA) ACCOMPANYING THE PRODUCT        *
//PERMITS THE REGISTERED DEVELOPER TO REDISTRIBUTE THE PRODUCT IN       *
//EXECUTABLE FORM ONLY IN SUPPORT OF APPLICATIONS WRITTEN USING         *
//THE PRODUCT.  IT DOES NOT PROVIDE ANY RIGHTS REGARDING THE            *
//SOURCE CODE CONTAINED HEREIN.                                         *
//                                                                      *
//THIS COPYRIGHT NOTICE MAY NOT BE REMOVED FROM THIS FILE.              *
//--------------------------------------------------------------------- *
#endregion
using System;
using System.Text;
using System.Xml;
using System.ComponentModel;
using System.Collections;
using Widgetsphere.Generator.Common.GeneratorFramework;
using Widgetsphere.Generator.Common.Util;
using System.Drawing.Design;

namespace Widgetsphere.Generator.Models
{
  [
  Designer(typeof(Widgetsphere.Generator.Design.Designers.TableDesigner)),
  DesignTimeVisible(true),
  ]
  public class CustomAggregate : BaseModelObject, ICodeFacadeObject
  {
    #region Member Variables

    protected const bool _def_generated = true;

    protected int _id = 1;
    protected string _name = "";
    protected string _codeFacade = "";
    protected string _description = "";
    protected bool _generated = _def_generated;
    protected string _sql = "";
    protected ReferenceCollection _columns = null;
    protected ReferenceCollection _parameters = null;
		private DateTime _createdDate = DateTime.Now;

    #endregion

    #region Constructor

    public CustomAggregate(IModelObject root)
      : base(root)
    {
      _columns = new ReferenceCollection(this.Root, this, ReferenceType.Column);
      _columns.ObjectPlural = "Columns";
      _columns.ObjectSingular = "Column";
      _columns.ImageIndex = ImageHelper.GetImageIndex(ImageConstants.FolderClose);
      _columns.SelectedImageIndex = ImageHelper.GetImageIndex(ImageConstants.FolderOpen);

      _parameters = new ReferenceCollection(this.Root, this, ReferenceType.Parameter);
      _parameters.ObjectPlural = "Parameters";
      _parameters.ObjectSingular = "Parameter";
      _parameters.ImageIndex = ImageHelper.GetImageIndex(ImageConstants.FolderClose);
      _parameters.SelectedImageIndex = ImageHelper.GetImageIndex(ImageConstants.FolderOpen);

    }

    #endregion

    #region Property Implementations

    [
    Browsable(true),
    Description("Determines the name of this table."),
    Category("Design"),
    DefaultValue("")
    ]
    public string Name
    {
      get { return _name; }
      set
      {
        _name = value;
        this.OnPropertyChanged(this, new PropertyChangedEventArgs("Name"));
      }
    }

    [
    Browsable(true),
    Description("Determines the description of this table."),
    Category("Data"),
    DefaultValue(""),
    ]
    public string Description
    {
      get { return _description; }
      set
      {
        _description = value;
        this.OnPropertyChanged(this, new PropertyChangedEventArgs("Description"));
      }
    }

    [
    Browsable(true),
    Description("Determines the columns that are associated with this table."),
    Category("Data"),
    TypeConverter(typeof(Widgetsphere.Generator.Design.Converters.ColumnReferenceCollectionConverter)),
    Editor(typeof(Widgetsphere.Generator.Design.Editors.ColumnReferenceCollectionEditor), typeof(System.Drawing.Design.UITypeEditor))
    ]
    public ReferenceCollection Columns
    {
      get
      {
        return _columns;
      }
    }

    [
    Browsable(true),
    Description("Determines the parameters that are associated with this rule."),
    Category("Data"),
    //TypeConverter(typeof(Widgetsphere.Generator.Design.Converters.ColumnReferenceCollectionConverter)),
    //Editor(typeof(Widgetsphere.Generator.Design.Editors.ColumnReferenceCollectionEditor), typeof(System.Drawing.Design.UITypeEditor))
    ]
    public ReferenceCollection Parameters
    {
      get { return _parameters; }
    }

    [Browsable(false)]
    public ReferenceCollection GeneratedColumns
    {
      get
      {
        ReferenceCollection retVal = new ReferenceCollection(this.Root);
        foreach(Reference reference in _columns)
        {
          CustomAggregateColumn dc = (CustomAggregateColumn)reference.Object;
          if(dc.Generated)
            retVal.Add(dc.CreateRef());
          else
            System.Diagnostics.Debug.Write("");
        }
        return retVal;
      }
    }

    [
    Browsable(true),
    Description("Determines if this item is used in the generation."),
    Category("Data"),
    DefaultValue(_def_generated),
    ]
    public bool Generated
    {
      get { return _generated; }
      set
      {
        _generated = value;
        this.OnPropertyChanged(this, new PropertyChangedEventArgs("Generated"));
      }
    }

    [
    Browsable(true),
    Description("Determines SQL statement used to create the database view object."),
    Category("Data"),
    Editor(typeof(Widgetsphere.Generator.Design.Editors.SQLEditor), typeof(UITypeEditor)),
    ]
    public string SQL
    {
      get { return _sql; }
      set
      {
        _sql = value;
        this.OnPropertyChanged(this, new PropertyChangedEventArgs("ViewSql"));
      }
    }

    [Browsable(false)]
    public int Id
    {
      get { return _id; }
    }

		[Browsable(true)]
		[Category("Data")]
		[Description("The date that this object was created.")]
		[ReadOnlyAttribute(true)]
		public DateTime CreatedDate
		{
			get { return _createdDate; }
		}

    #endregion

    #region Methods

    public override string ToString()
    {
      string retval = this.Name;
			//if(this.CodeFacade != "")
			//  retval += " AS " + this.CodeFacade;
			return retval;
    }

    protected internal System.Data.DataTable CreateDataTable()
    {
      System.Data.DataSet retval = new System.Data.DataSet();
      System.Data.DataTable t = retval.Tables.Add(this.Name);
      foreach(Reference reference in this.Columns)
      {
        Column column = (Column)reference.Object;
        System.Data.DataColumn c = t.Columns.Add(column.Name, typeof(string));
      }
      return retval.Tables[0];
    }

    #endregion

    #region IXMLable Members

    public override void XmlAppend(XmlNode node)
    {
      try
      {
        XmlDocument oDoc = node.OwnerDocument;
        XmlAttribute keyNode = oDoc.CreateAttribute("key");
        keyNode.Value = this.Key.ToString();
        node.Attributes.Append(keyNode);

        XmlAttribute name = oDoc.CreateAttribute("name");
        name.Value = this.Name;
        node.Attributes.Append(name);

        XmlAttribute codeFacade = oDoc.CreateAttribute("codeFacade");
        codeFacade.Value = this.CodeFacade;
        node.Attributes.Append(codeFacade);

        XmlAttribute description = oDoc.CreateAttribute("description");
        description.Value = this.Description;
        node.Attributes.Append(description);

        XmlNode columnsNode = oDoc.CreateElement("columns");
        this.Columns.XmlAppend(columnsNode);
        node.AppendChild(columnsNode);

        XmlNode parametersNode = oDoc.CreateElement("parameters");
        this.Parameters.XmlAppend(parametersNode);
        node.AppendChild(parametersNode);

        XmlNode viewSqlNode = oDoc.CreateElement("sql");
        viewSqlNode.AppendChild(oDoc.CreateCDataSection(this.SQL));
        node.AppendChild(viewSqlNode);

        XmlAttribute generated = oDoc.CreateAttribute("generated");
        generated.Value = this.Generated.ToString();
        node.Attributes.Append(generated);

        XmlAttribute id = oDoc.CreateAttribute("id");
        id.Value = this.Id.ToString();
        node.Attributes.Append(id);

				XmlAttribute created = oDoc.CreateAttribute("createdDate");
				created.Value = _createdDate.ToString("yyyy-MM-dd HH:mm:ss");
				node.Attributes.Append(created);

      }
      catch(Exception ex)
      {
        throw;
      }

    }

    public override void XmlLoad(XmlNode node)
    {
      try
      {
        _key = XmlHelper.GetAttributeValue(node, "key", _key);
        this.Name = node.Attributes["name"].Value;
        this.CodeFacade = XmlHelper.GetAttributeValue(node, "codeFacade", "");
        this.Description = node.Attributes["description"].Value;
        this.SQL = XmlHelper.GetNodeValue(node, "sql", "");
        XmlNode columnsNode = node.SelectSingleNode("columns");
        Columns.XmlLoad(columnsNode);

        XmlNode parametersNode = node.SelectSingleNode("parameters");
        if(parametersNode != null)
          this.Parameters.XmlLoad(parametersNode);

        this.Generated = bool.Parse(node.Attributes["generated"].Value);
        this.SetId(int.Parse(node.Attributes["id"].Value));
				_createdDate = DateTime.ParseExact(XmlHelper.GetAttributeValue(node, "createdDate", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")), "yyyy-MM-dd HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture);

        this.Dirty = false;
      }
      catch(Exception ex)
      {
        throw;
      }
    }

    #endregion

    #region Helpers

    public Reference CreateRef()
    {
      Reference returnVal = new Reference(this.Root);
      returnVal.Ref = this.Id;
      returnVal.RefType = ReferenceType.CustomAggregateColumn;
      return returnVal;
    }

    [Browsable(false)]
    public string CamelName
    {
			//get { return StringHelper.DatabaseNameToCamelCase(this.Name); }
			get { return StringHelper.DatabaseNameToCamelCase(this.PascalName); }
		}

    [Browsable(false)]
    public string PascalName
    {
			get
			{
				if (this.CodeFacade != "")
					return StringHelper.DatabaseNameToPascalCase(this.CodeFacade);
				else
					return StringHelper.DatabaseNameToPascalCase(this.Name);
			}
		}

    [Browsable(false)]
    public string DatabaseName
    {
      get { return this.Name; }
    }

    [
    Browsable(false),
    Description("Determines the fields that constitute the table primary key."),
    Category("Data"),
    DefaultValue(""),
    Editor(typeof(Widgetsphere.Generator.Design.Editors.NullEditor), typeof(System.Drawing.Design.UITypeEditor)),
    TypeConverter(typeof(Widgetsphere.Generator.Design.Converters.TablePrimaryKeyConverter)),
    ]
    public ArrayList PrimaryKeyColumns
    {
      get
      {
        ArrayList primaryKeyColumns = new ArrayList();
        foreach(Reference columnRef in this.Columns)
        {
          Column column = (Column)columnRef.Object;
          if(column.PrimaryKey)
          {
            primaryKeyColumns.Add(column);
          }
        }
        return primaryKeyColumns;
      }
    }

    protected internal void SetId(int id)
    {
      _id = id;
    }

    #endregion

    #region ICodeFacadeObject Members

    [
    Browsable(true),
    Description("Determines the object name used in the API. If this property is blank the 'Name' property is used in the API. This property can be used to mask the database identifier."),
    Category("Design"),
    DefaultValue(""),
    ]
    public string CodeFacade
    {
      get { return _codeFacade; }
      set
      {
        _codeFacade = value;
        this.OnPropertyChanged(this, new PropertyChangedEventArgs("codeFacade"));
      }
    }

    public string GetCodeFacade()
    {
      if(this.CodeFacade == "")
        return this.Name;
      else
        return this.CodeFacade;
    }

    #endregion

  }
}